package com.shenyuan.module_basekt.base

import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.Toast
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import com.alibaba.android.arouter.launcher.ARouter
import java.lang.reflect.ParameterizedType

/**
 * @author ch
 * @date 2022/7/25-16:30
 * desc
 */
abstract class BaseVMActivity<VB : ViewDataBinding, VM : BaseViewModel> : FragmentActivity(), LifecycleOwner, ViewModelStoreOwner {


    val binding: VB by lazy {
        createDataBinding()
    }

    val viewModel: VM by lazy {
        createViewModel()
    }

    var content: Context? = null

    var provider: ViewModelProvider? = null


    /**
     * 创建viewModel
     */
    abstract fun createViewModel(): VM

    /**
     * 初始view
     */
    abstract fun initView()

    /**
     * 添加事件
     */
    abstract fun addListener()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        content = this;
        ARouter.getInstance().inject(this)
        setContentView(binding.root)
        initView()
        addListener()
    }

    private fun createDataBinding(): VB {
        return getBindingType(javaClass)
                ?.getMethod("inflate", LayoutInflater::class.java)
                ?.invoke(null, LayoutInflater.from(this)) as VB
    }


    fun <T : ViewModel> getScopeViewModel(clazz: Class<T>): T {
        if (provider == null) {
            provider = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))
        }
        return provider!!.get(clazz)
    }

    /**
     * toast
     */
    fun showToast(msg: String) {
        val toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT)
        toast.setGravity(Gravity.CENTER, 0, 0)
        toast.show()
    }

    /**
     * 获取当前 Activity 上 ViewDataBinding 的实际类型
     */
    fun getBindingType(clazz: Class<*>): Class<*>? {
        val superClass = clazz.genericSuperclass
        if (superClass is ParameterizedType) {
            //返回表示此类型实际类型参数的 Type 对象的数组
            val argment = superClass.actualTypeArguments
            return argment.firstOrNull {
                // 判断是 Class 类型 且是 ViewDataBinding 的子类
                it is Class<*> && ViewDataBinding::class.java.isAssignableFrom(it)
            } as? Class<*>
        }
        return null
    }

}